package org.jeecg.modules.finance.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.business.dto.MobileDto;
import org.jeecg.modules.business.entity.BusOrderFee;
import org.jeecg.modules.business.entity.BusRoomBookingOrders;
import org.jeecg.modules.business.entity.BusRoomsLivingOrder;
import org.jeecg.modules.business.entity.BusWaiter;
import org.jeecg.modules.business.enums.FeeSubjectType;
import org.jeecg.modules.business.service.IBusOrderFeeService;
import org.jeecg.modules.business.service.IBusRoomsLivingOrderService;
import org.jeecg.modules.business.service.IBusWaiterService;
import org.jeecg.modules.finance.service.ISummaryService;
import org.jeecg.modules.finance.vo.OrderFeeVo;
import org.jeecg.modules.finance.vo.PayTypeStatVo;
import org.jeecg.modules.finance.vo.RoomStatVo;
import org.jeecg.modules.fw.dto.RoomCleanDto;
import org.jeecg.modules.fw.entity.FwRoomClean;
import org.jeecg.modules.fw.service.IFwRoomCleanService;
import org.jeecg.modules.kc.enums.StorageEnum;
import org.jeecg.modules.pos.entity.PosOrderGoodsPayment;
import org.jeecg.modules.rooms.Enum.RoomStatusEnum;
import org.jeecg.modules.rooms.entity.CesRoomLayoutPriceDate;
import org.jeecg.modules.rooms.entity.CesRooms;
import org.jeecg.modules.rooms.service.CesRoomsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 收款统计
 * @Author: jeecg-boot
 * @Date:   2023-04-19
 * @Version: V1.0
 */
@Api(tags="收款统计")
@RestController
@RequestMapping("/finance/summary")
@Slf4j
public class SummaryController {
	@Resource
	private ISummaryService summaryService;
	@Resource
	private IBusOrderFeeService busOrderFeeService;
	/**
	 * 收款汇总统计
	 *
	 * @param posOrderGoodsPayment
	 * @param pageNo
	 * @param pageSize
	 * @param startTime
	 * @param endTime
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "收款汇总统计", notes = "收款汇总统计")
	@GetMapping(value = "/financeSummaryPage")
	public Result<IPage<HashMap<String, Object>>> getFinanceSummarizationPage(PosOrderGoodsPayment posOrderGoodsPayment,
																			  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
																			  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
																			  @RequestParam(name = "startTime", required = false) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																			  @RequestParam(name = "endTime", required = false) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime,
																			  @RequestParam(name = "departmentId", defaultValue = "0") Integer departmentId,
																			  HttpServletRequest req) {
		Page<HashMap<String, Object>> page = new Page<HashMap<String, Object>>(pageNo, pageSize);
		IPage<HashMap<String, Object>> pageList = summaryService.pageList(page, posOrderGoodsPayment.getHotelId(), startTime, endTime, departmentId);
		return Result.OK(pageList);
	}

	/**
	 * 收退款明细
	 * @param posOrderGoodsPayment
	 * @param pageNo
	 * @param pageSize
	 * @param startTime
	 * @param endTime
	 * @param departmentId
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "收退款明细", notes = "收退款明细")
	@GetMapping(value = "/financePage")
	public Result<IPage<HashMap<String, Object>>> getFinancePageList(PosOrderGoodsPayment posOrderGoodsPayment,
																			  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
																			  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
																			  @RequestParam(name = "startTime", required = false) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																			  @RequestParam(name = "endTime", required = false) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime,
																			  @RequestParam(name = "departmentId", defaultValue = "0") Integer departmentId,
																			  HttpServletRequest req) {
		Page<HashMap<String, Object>> page = new Page<HashMap<String, Object>>(pageNo, pageSize);
		IPage<HashMap<String, Object>> pageList = summaryService.financePageList(page, posOrderGoodsPayment.getHotelId(), startTime, endTime, departmentId);
		return Result.OK(pageList);
	}

	@ApiOperation(value = "当天收入统计", notes = "当天收入统计")
	@GetMapping(value = "/currentDayFinanceSummary")
	public Result getCurrentDayFinanceSummary(@RequestParam String hotelId) {
		if (StringUtils.isBlank(hotelId)) {
			return Result.error("请传入酒店id");
		}
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(DateTime.now());
		calendar.add(Calendar.DATE, 1);
		String dateString = formatter.format(calendar.getTime());

		LambdaQueryWrapper<BusOrderFee> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
		lambdaQueryWrapper2.eq(BusOrderFee::getHotelId, hotelId);
		lambdaQueryWrapper2.eq(BusOrderFee::getFeeType, 2);
		lambdaQueryWrapper2.ge(BusOrderFee::getCreateTime, LocalDate.now());
		lambdaQueryWrapper2.le(BusOrderFee::getCreateTime, DateUtil.parseDate(dateString));
		List<BusOrderFee> busOrderFees = busOrderFeeService.list(lambdaQueryWrapper2);
		Map<Integer, List<BusOrderFee>> map = busOrderFees.stream().collect(Collectors.groupingBy(t -> t.getSubjectType()));

		List<OrderFeeVo> data = new ArrayList<>();
		BigDecimal sum = BigDecimal.ZERO;
		for (Integer key : map.keySet()) {
			OrderFeeVo vo = new OrderFeeVo();
			FeeSubjectType feeSubjectType = FeeSubjectType.val(key);
			if (feeSubjectType != null) {
				vo.setName(feeSubjectType.getTitle());
			}
			List<BusOrderFee> busOrderFees1 = map.get(key);
			for (BusOrderFee busOrderFee : busOrderFees1) {
				sum = sum.add(busOrderFee.getMoney());
			}
			vo.setAmount(sum);
			data.add(vo);
		}
		return Result.OK(data);
	}

	/**
	 *
	 * @param hotelId 酒店id
	 * @param startTime 开始日期
	 * @param endTime 截至日期
	 * @param section 1天 2月 3季度 4年
	 * @return
	 */
	@ApiOperation(value = "当天收入统计", notes = "当天收入统计")
	@GetMapping(value = "/shouRuStatList")
	public Result<List<HashMap<String, Object>>> getDayShouRuStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
											  @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime,
											  @RequestParam(name = "section", defaultValue = "1") Integer section) {
		List<HashMap<String, Object>> list = summaryService.dayShouRuStatList(hotelId, startTime, endTime, section);
		return Result.OK(list);
	}

	@ApiOperation(value = "按收款方式收入统计列表", notes = "按收款方式收入统计列表")
	@GetMapping(value = "/payMethodStatList")
	public Result<List<HashMap<String, Object>>> getPayMethodStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																	  @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.payMethodStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按房型收入统计列表", notes = "按房型收入统计列表")
	@GetMapping(value = "/layoutStatList")
	public Result<List<HashMap<String, Object>>> getLayoutStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																	  @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.layoutStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按费项收入统计列表", notes = "按费项收入统计列表")
	@GetMapping(value = "/subjectTypeStatList")
	public Result<List<HashMap<String, Object>>> getSubjectTypeStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																   @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.subjectTypeStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按来源各项统计列表", notes = "按来源各项统计列表")
	@GetMapping(value = "/livingSourceStatList")
	public Result<List<HashMap<String, Object>>> getLivingSourceStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																		@RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.livingSourceStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按客型各项统计列表", notes = "按客型各项统计列表")
	@GetMapping(value = "/customerTypeStatList")
	public Result<List<HashMap<String, Object>>> getCustomerTypeStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																		 @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.customerTypeStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按入住类型各项统计列表", notes = "按入住类型各项统计列表")
	@GetMapping(value = "/livingTypeStatList")
	public Result<List<HashMap<String, Object>>> getLivingTypeStatList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																		 @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.livingTypeStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按房间统计当日收入明细列表", notes = "按房间统计当日收入明细列表")
	@GetMapping(value = "/roomStatDetailList")
	public Result<List<RoomStatVo>> getRoomStatDetailList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
														  @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<RoomStatVo> list = summaryService.roomStatList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按时间统计当日收入明细列表", notes = "按时间统计当日收入明细列表")
	@GetMapping(value = "/dayOrderFeeList")
	public Result<List<HashMap<String,Object>>> getDayOrderFeeList(@RequestParam String hotelId, @RequestParam(name = "startTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime startTime,
																   @RequestParam(name = "endTime", required = true) @JsonFormat(pattern = "yyyy-MM-dd")  @DateTimeFormat(pattern="yyyy-MM-dd") DateTime endTime) {
		List<HashMap<String, Object>> list = summaryService.dayOrderFeeList(hotelId, startTime, endTime);
		return Result.OK(list);
	}

	@ApiOperation(value = "按收款方式统计当日收入明细列表", notes = "按收款方式统计当日收入明细列表")
	@GetMapping(value = "/dayPayTypeList")
	public Result<List<PayTypeStatVo>> getDayPayTypeList(@RequestParam String hotelId) {
		List<PayTypeStatVo> list = summaryService.dayPayTypeList(hotelId);
		return Result.OK(list);
	}

	@ApiOperation(value = "按事项统计当日支出明细列表", notes = "按事项统计当日支出明细列表")
	@GetMapping(value = "/dayMatterExpendDetailList")
	public Result<List<HashMap<String,Object>>> getDayMatterExpendDetailList(@RequestParam String hotelId) {
		List<HashMap<String, Object>>  list = summaryService.dayMatterExpendDetailList(hotelId);
		return Result.OK(list);
	}

	@ApiOperation(value = "按时间统计当日支出明细列表", notes = "按时间统计当日支出明细列表")
	@GetMapping(value = "/dayExpendOrderFeeList")
	public Result<List<HashMap<String,Object>>> getDayExpendOrderFeeList(@RequestParam String hotelId) {
		List<HashMap<String, Object>>  list = summaryService.dayExpendOrderFeeList(hotelId);
		return Result.OK(list);
	}

	@ApiOperation(value = "按退款方式统计当日支出明细列表", notes = "按退款方式统计当日支出明细列表")
	@GetMapping(value = "/dayPayTypeExpendList")
	public Result<List<PayTypeStatVo>> getDayPayTypeExpendList(@RequestParam String hotelId) {
		List<PayTypeStatVo>  list = summaryService.dayPayTypeExpendList(hotelId);
		return Result.OK(list);
	}

	@ApiOperation(value = "收支情况统计", notes = "收支情况统计")
	@GetMapping(value = "/financeSummary")
	public Result<List<HashMap<String,Object>>> getFinanceSummary(@RequestParam String hotelId,@RequestParam Integer section) {
		List<HashMap<String,Object>> list = summaryService.financeSummary(hotelId,section);
		return Result.OK(list);
	}
}
